<template>
  <div class="technical-blog">
    <div class="blog-header">
      <h1>技术博客</h1>
      <div class="header-buttons">
        <div class="search-box">
          <input
            type="text"
            v-model="searchKeyword"
            placeholder="搜索文章..."
            @keyup.enter="handleSearch"
          />
          <button @click="handleSearch">搜索</button>
        </div>
        <button
          v-if="isAdmin"
          class="new-article-btn"
          @click="showNewArticleModal = true"
        >
          发布文章
        </button>
        <a @click="goToHome" class="action-button">
          <span class="button-content">主页</span>
          <span class="button-glow"></span>
          <span class="button-hover"></span>
        </a>
      </div>
    </div>

    <!-- 加载状态 -->
    <div v-if="loading" class="loading">
      <el-loading :fullscreen="false" />
    </div>

    <!-- 文章列表 -->
    <div v-else class="articles-container">
      <div v-for="article in articles" :key="article.id" class="article-card">
        <div class="article-header">
          <h2>{{ article.title }}</h2>
          <div class="article-meta">
            <span>{{ formatDate(article.createTime) }}</span>
            <div class="article-stats">
              <span class="view-count">
                {{ article.viewCount || 0 }}
              </span>
              <span class="like-count">
                {{ article.likeCount || 0 }}
              </span>
            </div>
          </div>
        </div>
        <div class="article-content">
          {{ article.content }}
        </div>
        <div class="article-footer">
          <div class="article-tags" v-if="article.tags">
            <span v-for="tag in article.tags" :key="tag.id" class="tag">{{ tag.name }}</span>
          </div>
          <div class="article-actions">
            <button v-if="isAdmin" @click="editArticle(article)" class="edit-btn">编辑</button>
            <button v-if="isAdmin" @click="deleteArticle(article.id)" class="delete-btn">删除</button>
            <button 
              class="like-btn" 
              @click="likeArticle(article.id)"
              :class="{ 'liked': likedArticles.has(article.id) }"
              :disabled="likedArticles.has(article.id)"
            >
              {{ article.likeCount || 0 }}赞
            </button>
          </div>
        </div>
      </div>
    </div>

    <!-- 分页 -->
    <div class="pagination">
      <el-pagination
        :current-page="currentPage"
        :page-size="pageSize"
        :total="total"
        :page-sizes="[10, 20, 30, 50]"
        layout="total, sizes, prev, pager, next"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <!-- 新建文章模态框 -->
    <div v-if="showNewArticleModal" class="modal">
      <div class="modal-content">
        <h2>写文章</h2>
        <div class="form-group">
          <input v-model="newArticle.title" placeholder="文章标题" />
        </div>
        <div class="form-group">
          <textarea v-model="newArticle.content" placeholder="文章内容" rows="10"></textarea>
        </div>
        <div class="modal-buttons">
          <button @click="createArticle">发布</button>
          <button @click="showNewArticleModal = false">取消</button>
        </div>
      </div>
    </div>

    <!-- 编辑文章模态框 -->
    <div v-if="showEditModal" class="modal">
      <div class="modal-content">
        <h2>编辑文章</h2>
        <div class="form-group">
          <input v-model="editingArticle.title" placeholder="文章标题" />
        </div>
        <div class="form-group">
          <textarea v-model="editingArticle.content" placeholder="文章内容" rows="10"></textarea>
        </div>
        <div class="modal-buttons">
          <button @click="updateArticle">保存</button>
          <button @click="showEditModal = false">取消</button>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import axios from 'axios';
import { ElMessage, ElMessageBox } from 'element-plus';
import router from '@/router';
import debounce from 'lodash/debounce';

export default {
  name: 'TechnicalBlog',
  data() {
    return {
      articles: [],
      showNewArticleModal: false,
      showEditModal: false,
      newArticle: {
        title: '',
        content: '',
        category: null,
        tags: []
      },
      editingArticle: {
        id: null,
        title: '',
        content: ''
      },
      isAdmin: false,
      loading: false,
      currentPage: 1,
      pageSize: 10,
      total: 0,
      searchKeyword: '',
      cachedArticles: new Map(),
      likedArticles: new Set(),
      likeAnimations: new Set()
    };
  },
  methods: {
    async fetchArticles() {
      try {
        this.loading = true;
        const response = await axios.get('/api/articles', {
          params: {
            page: this.currentPage - 1,
            size: this.pageSize,
            keyword: this.searchKeyword
          },
          headers: {
            'Authorization': 'Bearer ' + localStorage.getItem('jwtToken')
          }
        });
        
        // 更新文章列表
        this.articles = response.data.content.map(article => ({
          ...article,
          likeCount: article.likeCount || 0,
          viewCount: article.viewCount || 0
        }));
        
        this.total = response.data.totalElements;
        this.loading = false;
      } catch (error) {
        console.error('获取文章列表失败:', error);
        if (error.response && error.response.status === 401) {
          localStorage.removeItem('jwtToken');
          this.$router.push('/');
        }
        ElMessage.error('获取文章列表失败，请稍后重试');
        this.loading = false;
      }
    },
    handleSearch: debounce(function() {
      this.currentPage = 1;
      this.fetchArticles();
    }, 300),
    handleSizeChange(val) {
      this.pageSize = val;
      this.fetchArticles();
    },
    handleCurrentChange(val) {
      this.currentPage = val;
      this.fetchArticles();
    },
    async likeArticle(articleId) {
      try {
        if (this.likedArticles.has(articleId)) {
          return;
        }

        // 立即更新UI
        const articleIndex = this.articles.findIndex(a => a.id === articleId);
        if (articleIndex !== -1) {
          this.articles[articleIndex].likeCount = (this.articles[articleIndex].likeCount || 0) + 1;
          this.likedArticles.add(articleId);
        }

        // 发送请求到服务器
        await axios.post(`/api/articles/${articleId}/like`, null, {
          headers: {
            'Authorization': 'Bearer ' + localStorage.getItem('jwtToken')
          }
        });
        
        // 缓存点赞状态
        localStorage.setItem(`liked_${articleId}`, 'true');
      } catch (error) {
        // 如果请求失败，回滚UI更新
        const articleIndex = this.articles.findIndex(a => a.id === articleId);
        if (articleIndex !== -1) {
          this.articles[articleIndex].likeCount--;
          this.likedArticles.delete(articleId);
        }
        console.error('点赞失败:', error);
        if (error.response && error.response.status === 401) {
          localStorage.removeItem('jwtToken');
          this.$router.push('/');
        }
        ElMessage.error('点赞失败，请稍后重试');
      }
    },
    async createArticle() {
      if (!this.newArticle.title || !this.newArticle.content) {
        ElMessage.warning('标题和内容不能为空');
        return;
      }

      try {
        const token = localStorage.getItem('jwtToken');
        if (!token) {
          ElMessage.error('未登录或登录已过期');
          this.$router.push('/');
          return;
        }

        const response = await axios.post('/api/articles', {
          title: this.newArticle.title,
          content: this.newArticle.content
        }, {
          headers: {
            'Authorization': `Bearer ${token}`,
            'Content-Type': 'application/json'
          }
        });

        if (response.data) {
          ElMessage.success('文章发布成功');
          this.showNewArticleModal = false;
          this.newArticle = { title: '', content: '' };
          await this.fetchArticles();
        }
      } catch (error) {
        console.error('发布文章失败:', error);
        if (error.response) {
          switch (error.response.status) {
            case 403:
              ElMessage.error('没有权限执行此操作');
              break;
            case 401:
              ElMessage.error('登录已过期，请重新登录');
              localStorage.removeItem('jwtToken');
              this.$router.push('/');
              break;
            default:
              ElMessage.error('发布失败，请稍后重试');
          }
        } else {
          ElMessage.error('网络错误，请稍后重试');
        }
      }
    },
    editArticle(article) {
      if (!this.isAdmin) {
        ElMessage.warning('只有管理员才能编辑文章');
        return;
      }
      this.editingArticle = { 
        id: article.id,
        title: article.title,
        content: article.content
      };
      this.showEditModal = true;
    },
    async updateArticle() {
      if (!this.isAdmin) {
        ElMessage.warning('普通用户无权限修改文章');
        return;
      }

      const token = localStorage.getItem('jwtToken');
      if (!token) {
        ElMessage.error('未登录或登录已过期');
        this.$router.push('/');
        return;
      }

      try {
        // 验证用户角色
        const roleResponse = await axios.get('/api/user/role', {
          headers: {
            'Authorization': `Bearer ${token}`
          }
        });

        if (roleResponse.data.role !== 'ROLE_ADMIN') {
          ElMessage.error('没有权限执行此操作');
          return;
        }

        const response = await axios.put(`/api/articles/${this.editingArticle.id}`, {
          title: this.editingArticle.title,
          content: this.editingArticle.content
        }, {
          headers: {
            'Authorization': `Bearer ${token}`,
            'Content-Type': 'application/json'
          }
        });

        // 更新本地文章数据
        const index = this.articles.findIndex(a => a.id === this.editingArticle.id);
        if (index !== -1) {
          this.articles[index] = { ...this.articles[index], ...response.data };
        }

        ElMessage.success('文章更新成功');
        this.showEditModal = false;
      } catch (error) {
        console.error('更新文章失败:', error);
        if (error.response) {
          switch (error.response.status) {
            case 403:
              ElMessage.error('没有权限执行此操作');
              break;
            case 401:
              ElMessage.error('登录已过期，请重新登录');
              localStorage.removeItem('jwtToken');
              this.$router.push('/');
              break;
            default:
              ElMessage.error(`更新失败: ${error.response.data.message || '未知错误'}`);
          }
        } else {
          ElMessage.error('网络错误，请稍后重试');
        }
      }
    },
    async deleteArticle(articleId) {
      if (!this.isAdmin) {
        ElMessage.warning('普通用户无权限删除文章');
        return;
      }

      const token = localStorage.getItem('jwtToken');
      if (!token) {
        ElMessage.error('未登录或登录已过期');
        this.$router.push('/');
        return;
      }

      try {
        // 验证用户角色
        const roleResponse = await axios.get('/api/user/role', {
          headers: {
            'Authorization': `Bearer ${token}`
          }
        });

        if (roleResponse.data.role !== 'ROLE_ADMIN') {
          ElMessage.error('没有权限执行此操作');
          return;
        }

        await ElMessageBox.confirm('确定要删除这篇文章吗？', '警告', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        });

        await axios.delete(`/api/articles/${articleId}`, {
          headers: {
            'Authorization': `Bearer ${token}`,
            'Content-Type': 'application/json'
          }
        });

        // 从本地列表中移除文章
        this.articles = this.articles.filter(article => article.id !== articleId);
        ElMessage.success('文章删除成功');

        // 如果当前页没有文章了，且不是第一页，则跳转到上一页
        if (this.articles.length === 0 && this.currentPage > 1) {
          this.currentPage--;
          await this.fetchArticles();
        }
      } catch (error) {
        if (error === 'cancel') {
          return;
        }
        
        console.error('删除文章失败:', error);
        if (error.response) {
          switch (error.response.status) {
            case 403:
              ElMessage.error('没有权限执行此操作');
              break;
            case 401:
              ElMessage.error('登录已过期，请重新登录');
              localStorage.removeItem('jwtToken');
              this.$router.push('/');
              break;
            default:
              ElMessage.error(`删除失败: ${error.response.data.message || '未知错误'}`);
          }
        } else {
          ElMessage.error('网络错误，请稍后重试');
        }
      }
    },
    formatDate(dateString) {
      const date = new Date(dateString);
      return date.toLocaleDateString('zh-CN', {
        year: 'numeric',
        month: 'long',
        day: 'numeric'
      });
    },
    async checkAdminStatus() {
      const token = localStorage.getItem('jwtToken');
      if (!token) {
        this.isAdmin = false;
        return;
      }

      try {
        const response = await axios.get('/api/user/role', {
          headers: {
            'Authorization': `Bearer ${token}`
          }
        });
        
        console.log('User role response:', response.data);
        this.isAdmin = response.data.role === 'ROLE_ADMIN';
        console.log('Is admin:', this.isAdmin);
      } catch (error) {
        console.error('Error fetching user role:', error);
        this.isAdmin = false;
        if (error.response && error.response.status === 401) {
          localStorage.removeItem('jwtToken');
          this.$router.push('/');
        }
      }
    },
    goToHome() {
      const token = localStorage.getItem('jwtToken');
      if (token) {
        router.push('/Blog');
      } else {
        router.push('/');
      }
    }
  },
  mounted() {
    this.fetchArticles();
    this.checkAdminStatus();
    
    // 从localStorage恢复点赞状态
    this.articles.forEach(article => {
      if (localStorage.getItem(`liked_${article.id}`) === 'true') {
        this.likedArticles.add(article.id);
      }
    });
  },
  beforeUnmount() {
    this.cachedArticles.clear();
  }
};
</script>

<style scoped>
.technical-blog {
  min-height: 100vh;
  background: linear-gradient(135deg, #1a1a2e 0%, #16213e 100%);
  padding: 2rem;
  color: #fff;
  width: 100%;
  box-sizing: border-box;
  overflow-x: hidden;
}

.blog-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 2rem;
}

.blog-header h1 {
  font-size: 2.5rem;
  color: #00fff2;
  text-shadow: 0 0 10px rgba(0, 255, 242, 0.5);
}

.header-buttons {
  display: flex;
  gap: 1rem;
  align-items: center;
}

.search-box {
  display: flex;
  gap: 0.5rem;
  margin-right: 1rem;
}

.search-box input {
  padding: 0.5rem;
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 4px;
  background: rgba(255, 255, 255, 0.1);
  color: #fff;
  width: 200px;
}

.search-box button {
  padding: 0.5rem 1rem;
  background: rgba(0, 255, 242, 0.1);
  border: 1px solid #00fff2;
  color: #00fff2;
  border-radius: 4px;
  cursor: pointer;
  min-width: 80px;
}

.new-article-btn {
  background: rgba(0, 255, 242, 0.1);
  border: 1px solid #00fff2;
  color: #00fff2;
  padding: 0.5rem 1rem;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s ease;
  min-width: 80px;
  height: 38px;
  display: flex;
  align-items: center;
  justify-content: center;
}

.new-article-btn:hover {
  background: rgba(0, 255, 242, 0.2);
  transform: translateY(-2px);
}

.articles-container {
  display: grid;
  gap: 2rem;
  max-width: 1200px;
  margin: 0 auto;
  width: 100%;
  box-sizing: border-box;
}

.article-card {
  background: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(10px);
  border-radius: 12px;
  padding: 2rem;
  border: 1px solid rgba(255, 255, 255, 0.2);
  transition: transform 0.3s ease;
  width: 100%;
  box-sizing: border-box;
  position: relative;
}

.article-card:hover {
  transform: translateY(-5px);
}

.article-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 1rem;
}

.article-header h2 {
  color: #00fff2;
  margin: 0;
}

.article-meta {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: 0.5rem;
}

.article-stats {
  display: flex;
  gap: 1rem;
  color: rgba(255, 255, 255, 0.6);
  font-size: 0.9rem;
}

.view-count::before {
  content: '👁️ ';
}

.like-count::before {
  content: '❤️ ';
}

.article-footer {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid rgba(255, 255, 255, 0.1);
  width: 100%;
}

.article-tags {
  display: flex;
  gap: 0.5rem;
  flex: 1;
}

.article-actions {
  display: flex;
  gap: 0.5rem;
  align-items: center;
  justify-content: flex-end;
  margin-left: auto;
}

.edit-btn, .delete-btn {
  padding: 0.3rem 0.8rem;
  border-radius: 4px;
  cursor: pointer;
  background: transparent;
  border: 1px solid;
  transition: all 0.3s ease;
  white-space: nowrap;
  min-width: 60px;
}

.edit-btn {
  color: #00fff2;
  border-color: #00fff2;
}

.delete-btn {
  color: #ff3b30;
  border-color: #ff3b30;
}

.like-btn {
  background: transparent;
  border: 1px solid #00fff2;
  color: #00fff2;
  padding: 0.3rem 1rem;
  border-radius: 4px;
  cursor: pointer;
  transition: all 0.3s ease;
  min-width: 60px;
  text-align: center;
  white-space: nowrap;
}

.like-btn.liked {
  background: transparent;
  border-color: #ff5252;
  color: #ff5252;
}

.article-content {
  color: rgba(255, 255, 255, 0.8);
  line-height: 1.6;
}

.tag {
  padding: 0.2rem 0.5rem;
  background: rgba(0, 255, 242, 0.1);
  border: 1px solid #00fff2;
  color: #00fff2;
  border-radius: 4px;
  font-size: 0.8rem;
}

.modal {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: rgba(0, 0, 0, 0.7);
  display: flex;
  justify-content: center;
  align-items: center;
  z-index: 1000;
}

.modal-content {
  background: rgba(26, 26, 46, 0.95);
  padding: 2rem;
  border-radius: 12px;
  width: 90%;
  max-width: 800px;
  border: 1px solid rgba(0, 255, 242, 0.2);
}

.modal-content h2 {
  color: #00fff2;
  margin-bottom: 1.5rem;
}

.form-group {
  margin-bottom: 1.5rem;
}

.form-group input,
.form-group textarea {
  width: 100%;
  padding: 0.8rem;
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
  border-radius: 8px;
  color: #fff;
  font-size: 1rem;
}

.form-group textarea {
  resize: vertical;
  min-height: 200px;
}

.modal-buttons {
  display: flex;
  justify-content: flex-end;
  gap: 1rem;
}

.modal-buttons button {
  padding: 0.8rem 1.5rem;
  border-radius: 8px;
  cursor: pointer;
  transition: all 0.3s ease;
}

.modal-buttons button:first-child {
  background: rgba(0, 255, 242, 0.1);
  border: 1px solid #00fff2;
  color: #00fff2;
}

.modal-buttons button:last-child {
  background: rgba(255, 255, 255, 0.1);
  border: 1px solid rgba(255, 255, 255, 0.2);
  color: #fff;
}

.modal-buttons button:hover {
  transform: translateY(-2px);
}

.action-button {
  position: relative;
  width: 80px;
  height: 38px;
  background: rgba(4, 177, 255, 0.1);
  border: 1px solid rgba(4, 177, 255, 0.2);
  border-radius: 4px;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  overflow: hidden;
}

.button-content {
  color: #04b1ff;
  font-size: 16px;
  font-weight: 500;
  z-index: 1;
}

.button-glow {
  display: none;
}

.button-hover {
  display: none;
}

.action-button:hover {
  background: rgba(4, 177, 255, 0.2);
  border-color: #04b1ff;
}

.action-button:hover .button-content {
  color: white;
}

@media (max-width: 768px) {
  .header-buttons {
    flex-direction: row;
    gap: 0.5rem;
    align-items: center;
  }

  .search-box {
    flex: 1;
    margin-right: 0.5rem;
  }

  .search-box input {
    width: 100%;
    min-width: 120px;
  }

  .action-button {
    width: 80px;
    height: 38px;
  }

  .button-content {
    font-size: 16px;
    letter-spacing: normal;
  }
}

.loading {
  display: flex;
  justify-content: center;
  align-items: center;
  min-height: 200px;
}

.pagination {
  display: flex;
  justify-content: center;
  margin-top: 2rem;
  padding: 1rem;
}
</style> 